AWSアカウント名を含めたセキュリティ通知を作ってみる(AWS Organizations)
はじめに
AWS Organizations環境において「委任先アカウント上で 一部 Organizations APIを使える 」 ことを最近知りました。 例えば「AWSアカウント情報の確認」や「OU情報の確認」などです。 私の確認した範囲では、読み取り権限のアクションはおおよそ使えるようです。
今回はこの仕様を活用して「 AWSアカウント名を含めたセキュリティ通知 」 を作ってみます。 Security Hub のアラート通知 を題材としました。
(注意) 公式ドキュメント上で「どの Organizations APIが使えるようになるのか」や 「どのサービスでも委任すれば使えるようになるのか」といった情報は確認できていません。 探しましたが見つかりませんでした。記載を見つけた方教えて下さい!
前提条件
- AWS Organizations環境
- 監査アカウントへ Security Hub の組織利用を委任
- 監査アカウントに組織の Security Hub 検出結果を集約している
上記設定を前提とします。
※この設定を作るためのセットアップ例は以下ブログを参照ください。
作ったもの
監査アカウント上に以下のようなものを作りました。
参考: 構築のTerraformコード | GitHub Gist
【1. Security Hub 検出結果で「アラート対象」のものを検知】
部分
EventBridgeルールのイベントパターンは以下のようにしました。 CRITICALの検出結果で失敗しているコントロールを検知します。
{ "detail-type": ["Security Hub Findings - Imported"], "source": ["aws.securityhub"], "detail": { "findings": { "ProductName": ["Security Hub"], "Compliance": { "Status": [{ "anything-but": "PASSED" }] }, "RecordState": ["ACTIVE"], "Workflow": { "Status": ["NEW"] }, "Severity": { "Label": ["CRITICAL"] } } } }
※フィルタの深堀りは割愛します。以下ブログを参考ください。
【2. イベントを入力にStep Functionsステートマシンを実行】
部分
EventBridgeルールのターゲット設定は以下のとおり。Step Functionsステートマシンを指定します。
ターゲットにステートマシンを指定するときに、IAMロールが必要になります。
キャプチャの test-security-notifier-events-role
の部分です。
IAMロールのポリシーは以下のように
「ステートマシンの起動」のみを許可しています。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "states:StartExecution", "Resource": "${aws_sfn_state_machine.this.arn}" } ] }
【3. ステートマシン内でメッセージを生成、SNSトピックへ発行】
部分
ステートマシンの構成を貼ります。見てのとおりシンプルです。
### DescribeAccount 部分
Organizations:DescribeAccount
を実行します。
このアクションのパラメータには アカウントIDが必要です。
アカウントIDはEventBridgeイベントの $.detail.findings[0].AwsAccountId
を参照します。
出力では ResultPath を使って、アクション実行結果を追加します。 次の「SNS Publish」アクションでアカウント名を使うためです。
### SNS Publish 部分
SNS:Publish
で必要な APIパラメータを記述しているだけです。
以下のような内容にしました。
{ "TopicArn": "${発行したいSNSトピックのARN}", "Subject.$": "States.Format('Security Hubアラート(重要度: {}, アカウント: {})',$.detail.findings[0].Severity.Label,$.DescribeAccount.Account.Name)", "Message.$": "States.Format('アカウント {}({}) にて重要度 {} の {} 項目を検知しました。\n・タイトル: {}\n・リソースID: {}\n・リージョン: {}\n・発生時間: {}\n・修復の参考URL: {}', $.DescribeAccount.Account.Name,$.DescribeAccount.Account.Id,$.detail.findings[0].Severity.Label,$.detail.findings[0].Compliance.Status,$.detail.findings[0].Title,$.detail.findings[0].Resources[0].Id,$.region,$.time,$.detail.findings[0].Remediation.Recommendation.Url)" }
Subject と Message を以下に見やすく表示します。
組み込み関数のStates.Format
を活用して各テキストを作成しています。 アカウント名の情報は
$.DescribeAccount.Account.Name
にあります。
# Subject 構造 "Subject.$": "States.Format( 'Security Hubアラート(重要度: {}, アカウント: {})', $.detail.findings[0].Severity.Label, $.DescribeAccount.Account.Name )", # Message 構造 "Message.$": "States.Format( 'アカウント {}({}) にて重要度 {} の {} 項目を検知しました。\n ・タイトル: {}\n ・リソースID: {}\n ・リージョン: {}\n ・発生時間: {}\n ・修復の参考URL: {}', $.DescribeAccount.Account.Name, $.DescribeAccount.Account.Id, $.detail.findings[0].Severity.Label, $.detail.findings[0].Compliance.Status, $.detail.findings[0].Title, $.detail.findings[0].Resources[0].Id, $.region,$.time, $.detail.findings[0].Remediation.Recommendation.Url )"
通知確認
EメールでSNSトピックへサブスクライブしました。 確認できた通知を記載します。
通知例(その1)
アカウント Log Archive(111111111111) にて重要度 CRITICAL の FAILED 項目を検知しました。 ・タイトル: EC2.19 Security groups should not allow unrestricted access to ports with high risk ・リソースID: arn:aws:ec2:ap-northeast-1:111111111111:security-group/sg-0e1example ・リージョン: ap-northeast-1 ・発生時間: 2022-08-20T04:34:16Z ・修復の参考URL: https://docs.aws.amazon.com/console/securityhub/EC2.19/remediation
通知例(その2)
アカウント Audit(222222222222) にて重要度 CRITICAL の FAILED 項目を検知しました。 ・タイトル: IAM.6 Hardware MFA should be enabled for the root user ・リソースID: AWS::::Account:222222222222 ・リージョン: ap-northeast-1 ・発生時間: 2022-08-20T05:40:23Z ・修復の参考URL: https://docs.aws.amazon.com/console/securityhub/IAM.6/remediation
おわりに
AWSアカウント名を含めたセキュリティ通知を作ってみました。
マルチアカウント環境を運用していると「このアカウントIDなんだっけ…」 みたいなことを毎日思ってました。
なので「委任先アカウント上で Organizations API が使える」ことは嬉しいです。
「アカウント名情報を付与できる」メリットは多いです。 通知されたときの一手間が減ります。 アカウント命名規則を定めている環境では、「プロジェクト名でフィルタ」とかも簡単にできますよね。 嬉しいです。
以上、参考になれば幸いです。